import mind from '@/models/mind';
import { ObjectId } from 'mongodb';
import { getRelative } from '@/services/storyWithproject';
import { getSingleBranch } from '../gitlab/apis';
import { privateToken } from '../configs/gitlab';
import { syncPostNewBranch, syncProjectsSearch } from '../gitlab/index';

interface UpdateMind {
  id: string; // 需求id
  project_id: number; // 项目id
  project_name?: string; // 项目名称
  branch: string; // 分支名称
  env: string[]; // 开发环境
  developer?: string[]; // 开发人员
  [key: string]: any;
}

export const getMind = async () => {
  const list = await mind.getListWithStory();
  // const list = await mind.getList();
  return list;
};

export const updateMind = async (params: UpdateMind) => {
  const { id: story_id, project_id, project_name, branch, env, developer } = params;
  let temp_add: any = [];
  const temp_delete: any = [];
  const list = await mind.getList({
    story_id,
    project_id,
    branch,
  });
  // 获取已经存在env
  const curEnv: string[] = list.map((item) => item.env);
  // 如果没有这个需求的记录，那么新增
  if (!list || list.length === 0) {
    const data = env.map((item) => ({
      story_id,
      project_id,
      branch,
      project_name,
      env: item,
      developer,
      parentid: `${project_id}$${item}`,
    }));
    temp_add = temp_add.concat(data);
  } else {
    for (let i = 0; i < env.length; i += 1) {
      // 如果数据库里不存在这条记录，那么新增
      if (!curEnv.includes(env[i])) {
        temp_add.push({
          story_id,
          project_id,
          branch,
          project_name,
          env: env[i],
          developer,
          parentid: `${project_id}$${env[i]}`,
        });
      }
    }
  }
  for (let j = 0; j < curEnv.length; j += 1) {
    // 如果数据库里有而提交的时候没有，那么删除
    if (!env.includes(curEnv[j])) {
      temp_delete.push({
        story_id,
        project_id,
        branch,
        project_name,
        env: curEnv[j],
        developer,
      });
    }
  }
  if (temp_add.length) {
    Promise.all(
      temp_add.map(async (item) => {
        const cur = item;
        // 判断项目在环境上有没有合并分支
        const mergeBranch = await mind.findOne({
          project_id: item.project_id,
          env: item.env,
          isMergeBranch: true,
        });
        // 如果存在合并分支。那么挂到合并分支上。如果不存在正常插入
        if (mergeBranch && mergeBranch._id) {
          cur.parentid = `${String(mergeBranch._id)}`;
        }
        const result = await mind.insert(cur);
        return result;
      }),
    )
      .then((res) => {
        return res;
      })
      .catch((err) => {
        throw new Error('err');
      });
  }
  if (temp_delete.length) {
    Promise.all(
      temp_delete.map(async (item) => {
        const curBranch = await mind.findOne({ project_id: item.project_id, branch: item.branch, env: item.env });
        await mind.deleteOne({
          story_id: item.story_id,
          project_id: item.project_id,
          branch: item.branch,
          env: item.env,
        });
        if (curBranch && curBranch.parentid) {
          const brotherBranch = await mind.getList({ parentid: curBranch.parentid });
          const mergeBranch = await mind.findOne({
            project_id: item.project_id,
            env: item.env,
            isMergeBranch: true,
          });
          // if (brotherBranch.length === 1) {
          //   const brother = brotherBranch[0];
          //   // 删除合并分支
          //   await mind.deleteOne({ project_id, isMergeBranch: true, env: item.env });
          //   // 把剩下的兄弟分支挂到环境上
          //   await mind.update({ parentid: `${project_id}$${String(item.env)}` }, { branch: brother.branch, project_id: brother.project_id, story_id: brother.story_id });
          // }
          // 如果合并分支上没有节点了，那么删除这个合并分支
          if (mergeBranch && mergeBranch._id && brotherBranch.length === 0) {
            await mind.deleteOne({ _id: new ObjectId(curBranch.parentid) });
          }
        }
      }),
    )
      .then((res) => {
        return res;
      })
      .catch((err) => {
        throw new Error(err);
      });
  }
  return [];
};

// 需求删除项目。同步删除脑图
export const deleteMind = async (params: UpdateMind) => {
  const { project_id, id: story_id, branch, env: envs } = params;
  await mind.deleteMany({
    story_id,
    project_id,
    branch,
    env: { $in: envs },
  });
  const curList = await mind.getList({
    project_id,
    env: { $in: envs },
    isMergeBranch: { $exists: false },
  });
  if (curList.length === 0) {
    await mind.deleteMany({ project_id, isMergeBranch: true, env: { $in: envs } });
  }
  // 处理合并分支
  Promise.all(
    curList.map(async (item) => {
      const { parentid, env } = item;
      if (parentid) {
        const brotherBranch = await mind.getList({ parentid, project_id, env });
        // if (brotherBranch.length === 1) {
        //   const brother = brotherBranch[0];
        //   // 删除合并分支
        //   await mind.deleteOne({ project_id, isMergeBranch: true, env });
        //   // 把剩下的兄弟分支挂到环境上
        //   await mind.update({ parentid: `${project_id}$${String(env)}` }, { branch: brother.branch, project_id: brother.project_id, story_id: brother.story_id });
        // }
        // 如果合并分支上没有节点了，那么删除这个合并分支
        if (brotherBranch.length === 0) {
          await mind.deleteOne({ _id: new ObjectId(parentid) });
        }
      }
    }),
  )
    .then((res) => {
      return 'success';
    })
    .catch((err) => {
      throw new Error(err);
    });
  return [];
};

// 脑图创建合并分支
export const createMergeBranch = async (params: { projectId: number; mergeBranchName: string; node: string }) => {
  // info： 项目id$环境$分支名称$需求id
  const { projectId, mergeBranchName, node } = params;
  // // 判断gitlab上有没有这个分支
  // const branchRes: any = await getSingleBranch({ private_token: privateToken, id: Number(projectId), branch: mergeBranchName }).catch((err) => {
  //   return null;
  // });
  // // 如果不存在
  // if (!branchRes || !branchRes.name) {
  //   const project = await syncProjectsSearch({ id: Number(projectId) });
  //   let default_branch = 'master';
  //   if (project.length) {
  //     default_branch = project[0].default_branch;
  //   }
  //   // 往gitlab上发个创建合并分支的请求。基于主分支创建一个新的分支
  //   await syncPostNewBranch({ id: projectId, ref: default_branch, branch: mergeBranchName });
  // }
  // 往需求关联项目的表里新增这个分支
  const infoArr: string[] = node.split('$');
  const temp = {
    project_id: projectId,
    env: infoArr[1],
    parentid: `${node}`,
    branch: mergeBranchName,
    isMergeBranch: true,
  };
  // 插入新数据
  const newBranch: any = await mind.insert(temp);
  // 更新旧数据
  // 获取旧数据
  // const oldNode = await mind.getList({ parentid: node, isMergeBranch: { $exists: false } });
  // if (oldNode.length) {
  //   Promise.all(
  //     oldNode.map((item) => {
  //       return mind.update(
  //         { parentid: `${String(newBranch.insertedId)}` },
  //         {
  //           _id: item._id,
  //         },
  //       );
  //     }),
  //   );
  // }
  return newBranch;
};

// 根据需求id删除关联关系
export const deleteMindByStoryId = async (params) => {
  const { id } = params;
  // 获取需求关联的项目
  const res = await getRelative({ id });
  Promise.all(
    res.map(async (item) => {
      await deleteMind({
        project_id: item.project_id,
        id: item.id,
        branch: item.branch,
        env: item.env,
      });
    }),
  )
    .then(() => {
      return 'success';
    })
    .catch((err) => {
      throw new Error(err);
    });
};

// 移动。添加到合并分支
export const moveToMergeBranch = async (params) => {
  const { parentid, _id } = params;
  try {
    await mind.update(
      {
        parentid,
      },
      {
        _id: new ObjectId(_id),
      },
    );
  } catch (err) {
    throw new Error('fail');
  }
};

// 删除合并分支
export const deleteMergeBranch = async (params) => {
  const { _id, children, parentid } = params;
  await mind.deleteOne({ _id: new ObjectId(_id) });
  if (children.length) {
    const ids = children.map((item) => new ObjectId(item));
    mind.updateMany({ _id: { $in: ids } }, { parentid });
  }
  return 'success';
};

// 获取某项目某环境下的合并分支
export const getMergeBranchList = async (params) => {
  const { parentid } = params;
  const res = await mind.getList({
    parentid,
    isMergeBranch: true,
  });
  return res;
};
